package rbac

import (
	"context"
	"gitee.com/bobo-rs/creative-framework/pkg/algorithm/treenode"
	"gitee.com/bobo-rs/creative-framework/pkg/utils"
	"gitee.com/bobo-rs/innovideo-services/enums"
	"gitee.com/bobo-rs/innovideo-services/framework/dao"
	"gitee.com/bobo-rs/innovideo-services/framework/model"
	"gitee.com/bobo-rs/innovideo-services/library/exception"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/frame/g"
)

// SaveDepartment 保存部门数据
func (r *sRbac) SaveDepartment(ctx context.Context, depart model.DepartmentSaveInput) error {
	// 保存数据
	return dao.Department.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		res, err := dao.Department.Ctx(ctx).
			OmitEmpty().
			Save(depart.DepartmentItem)
		if err != nil {
			return exception.New(`保存部门数据失败`)
		}

		// 获取部门ID
		departId, err := res.LastInsertId()
		if err != nil {
			return exception.New(`保存部门数据失败，请重试`)
		}

		// 绑定角色数据
		if len(depart.RoleId) > 0 {
			err = r.SaveDepartmentRoles(ctx, uint(departId), depart.RoleId...)
		} else {
			// 移除之前角色
			err = r.RemoveDepartmentRoleByDepartId(ctx, uint(departId))
		}
		return err
	})
}

// GetDepartmentTreeList 获取部门列表-并构建成树形结构
func (r *sRbac) GetDepartmentTreeList(ctx context.Context) ([]map[string]interface{}, error) {
	// 获取部门树形列表(含禁用)
	departRows, err := r.ProcessDepartmentList(ctx, g.Map{
		dao.Department.Columns().Status: []enums.DepartStatus{
			enums.DepartStatusOk, enums.DepartStatusDisabled,
		},
	})
	if err != nil {
		return nil, err
	}

	// 是否有部门数据
	if len(departRows) == 0 {
		return nil, nil
	}

	// 获取部门人数
	peopleMap, err := r.GetDepartPeopleNumByDepartId(
		ctx, utils.NewArray(departRows).Units(dao.Department.Columns().Id)...,
	)
	if err != nil {
		return nil, err
	}

	// 是否有部门
	if len(peopleMap) > 0 {
		for _, item := range departRows {
			if num, ok := peopleMap[item.Id]; ok {
				item.PeopleNum = num
			}
		}
	}

	// 构建树形结构
	return treenode.New().BuildTree(departRows)
}

// GetDepartmentFindTreeList 获取部门树形列表并查找部门ID
func (r *sRbac) GetDepartmentFindTreeList(ctx context.Context, status enums.DepartStatus, departId ...uint) ([]map[string]interface{}, error) {
	// 获取部门树形列表
	departRows, err := r.ProcessDepartmentList(ctx, g.Map{
		dao.Department.Columns().Status: status,
	})
	if err != nil {
		return nil, err
	}

	// 构建树形结构数据
	return treenode.New().BuildFindTreeNode(departRows, departId)
}

// GetDepartmentDetail 获取部门详情
func (r *sRbac) GetDepartmentDetail(ctx context.Context, departId uint) (detail *model.DepartmentDetailItem, err error) {
	// 获取部门详情
	detail = &model.DepartmentDetailItem{}
	err = r.DepartmentModel().Scan(ctx, g.Map{
		dao.Department.Columns().Id: departId,
	}, &detail.DepartmentItem)
	if err != nil {
		return nil, exception.New(`暂无部门信息`)
	}

	// 获取绑定角色ID和角色名
	detail.RoleId, _ = r.GetDepartRoleIdByDepartId(ctx, departId)
	if len(detail.RoleId) > 0 {
		detail.RoleList, _ = r.GetRolesNameListByRoleId(ctx, detail.RoleId...)
	}
	return
}

// RemoveDepartment 删除部门
func (r *sRbac) RemoveDepartment(ctx context.Context, departId uint) error {
	if departId == 0 {
		return exception.New(`缺少部门ID`)
	}
	return dao.Department.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		_, err := tx.Ctx(ctx).Delete(dao.Department.Table(), g.Map{
			dao.Department.Columns().Id: departId,
		})
		if err != nil {
			return exception.New(`删除部门失败`)
		}
		// 解除角色关联
		return r.RemoveDepartmentRoleByDepartId(ctx, departId)
	})
}

// GetDepartNameByDepartId 通过部门ID获取部门名称
func (r *sRbac) GetDepartNameByDepartId(ctx context.Context, departId ...uint) (rows []model.DepartmentNameItem, err error) {
	rows = []model.DepartmentNameItem{}
	if len(departId) == 0 {
		return nil, exception.New(`缺少部门ID`)
	}

	// 获取部门名称
	err = r.DepartmentModel().Scan(ctx, g.Map{
		dao.Department.Columns().Id: departId,
	}, &rows)
	if err != nil {
		return nil, err
	}

	return rows, nil
}
